import * as THREE from "three";
import { PointerLockControls } from "three/examples/jsm/controls/PointerLockControls.js";
import { World } from "./world";

let moveForward = false;
let moveBackward = false;
let moveLeft = false;
let moveRight = false;
let canJump = false;
const velocity = new THREE.Vector3(); //速度
const direction = new THREE.Vector3(); //方向
const vertex = new THREE.Vector3(); //顶点
let prevTime = performance.now();

export const initLibrary2 = () => {
  // 1、获取canvas
  const canvas = document.getElementById("library") as HTMLElement;
  // 2、场景
  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0x88ccee);
  const axesHelper = new THREE.AxesHelper(1000);
  scene.add(axesHelper);
  // 3、相机（透视）
  const camera = new THREE.PerspectiveCamera(
    75, //视角
    window.innerWidth / window.innerHeight, //aspect视锥长宽比
    0.1, //near
    10000 //far
  );
  camera.rotation.order = "YXZ"; //默认旋转顺序是 'XYZ',设置相机旋转的顺序的属性。这个属性指定了欧拉角（Euler angles）的旋转顺序
  camera.lookAt(0, 0, 0);
  camera.position.set(0, 2, 10);
  scene.add(camera);
  // 添加相机控件-指针
  const controls = new PointerLockControls(camera, canvas);
  // 4、灯光
  const fillLight1 = new THREE.HemisphereLight(0x8dc1de, 0x00668d, 1.5);
  fillLight1.position.set(2, 1, 1);
  scene.add(fillLight1);

  const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5);
  directionalLight.position.set(-5, 25, -1);
  directionalLight.castShadow = true;
  directionalLight.shadow.camera.near = 0.01;
  directionalLight.shadow.camera.far = 500;
  directionalLight.shadow.camera.right = 30;
  directionalLight.shadow.camera.left = -30;
  directionalLight.shadow.camera.top = 30;
  directionalLight.shadow.camera.bottom = -30;
  directionalLight.shadow.mapSize.width = 1024;
  directionalLight.shadow.mapSize.height = 1024;
  directionalLight.shadow.radius = 4;
  directionalLight.shadow.bias = -0.00006;
  scene.add(directionalLight);
  // 5、渲染器
  const renderer = new THREE.WebGLRenderer({ canvas });
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 像素比（和浏览器一致）
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  let requestDelta = 0;
  let renderDelta = 0;
  let oldElapsedTime = 0;
  let timeScale = 1;
  //添加物理引擎，添加模型
  let world = new World(scene, camera);
  // 6、动画
  const clock = new THREE.Clock();
  const start = () => {
    requestDelta = clock.getDelta();//与上一帧时间时间差，返回上次执行该方法到本次调用之间的时间间隔
    //更新物理世界
    const elapsedTime = clock.getElapsedTime(); //getElapsedTime自启动之后的秒数,elapsedTime会一直累加
    const deltaTime = elapsedTime - oldElapsedTime;
    oldElapsedTime = elapsedTime;
    // 不成比例时间步长
    // let unscaledTimeStep=requestDelta+renderDelta+logicDelta;
    world.update(deltaTime * timeScale);
    // console.log(requestDelta,elapsedTime);
    // 渲染场景
    renderer.render(scene, camera);
    // renderDelta = clock.getDelta();
    // move(controls);
    requestAnimationFrame(start);
  };
  start();

  window.addEventListener("resize", () => {
    // 更新宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 更新相机的投影矩阵
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);
    // 设置像素比
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  });

  // document.addEventListener("keydown", onKeyDown);
  // document.addEventListener("keyup", onKeyUp);
  document.addEventListener("click", ()=>{
    controls.lock();
  });
};

function onKeyDown(event) {
  switch (event.code) {
    case "ArrowUp":
    case "KeyW":
      moveForward = true;
      break;

    case "ArrowLeft":
    case "KeyA":
      moveLeft = true;
      break;

    case "ArrowDown":
    case "KeyS":
      moveBackward = true;
      break;

    case "ArrowRight":
    case "KeyD":
      moveRight = true;
      break;

    case "Space":
      if (canJump === true) velocity.y += 350;
      canJump = false;
      break;
  }
}

function onKeyUp(event) {
  switch (event.code) {
    case "ArrowUp":
    case "KeyW":
      moveForward = false;
      break;

    case "ArrowLeft":
    case "KeyA":
      moveLeft = false;
      break;

    case "ArrowDown":
    case "KeyS":
      moveBackward = false;
      break;

    case "ArrowRight":
    case "KeyD":
      moveRight = false;
      break;
  }
}

function move(controls) {
  const time = performance.now();
  if (controls.isLocked === true) {
    const delta = (time - prevTime) / 1000;

    velocity.x -= velocity.x * 15.0 * delta;
    velocity.z -= velocity.z * 15.0 * delta;

    velocity.y -= 9.8 * 100.0 * delta; // 100.0 = mass

    direction.z = Number(moveForward) - Number(moveBackward);
    direction.x = Number(moveRight) - Number(moveLeft);
    direction.normalize(); // this ensures consistent movements in all directions

    if (moveForward || moveBackward) velocity.z -= direction.z * 400.0 * delta;
    if (moveLeft || moveRight) velocity.x -= direction.x * 400.0 * delta;

    controls.moveRight(-velocity.x * delta);
    controls.moveForward(-velocity.z * delta);

    controls.getObject().position.y += velocity.y * delta; // new behavior

    if (controls.getObject().position.y < 10) {
      velocity.y = 0;
      controls.getObject().position.y = 2;

      canJump = true;
    }
  }

  prevTime = time;
}
